/*	This file is part of LSAC.

	LSAC is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	LSAC is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with LSAC.  If not, see <http://www.gnu.org/licenses/>.

	Copyright (c) 2010 LEPESME "Jiboo" Jean-Baptiste
*/

#pragma once

#include <string>
#include <list>
#include <boost/regex.hpp>
using namespace std;
using namespace boost;

#include "cASTree.h"
#include "cLexer.h"
#include "cExpression.h"
#include "cBlock.h"
#include "cStatement.h"
#include "eType.h"

#define POP_TOKEN(pLex, pName) \
	cToken *pName = pLex.pop();\
	if(pName == NULL) ERROR("Erreur, fin de fichier atteint, '" #pName "' manquant.")

#define POP_TOKEN_EXCEPT_VAL(pLex, pName, pExpectedValue) \
	POP_TOKEN(pLex, pName); \
	if(*pName != pExpectedValue) ERROR("Erreur, trouve '" << pName << "' alors que j' attendais '" << pExpectedValue << "'.")

#define POP_TOKEN_EXCEPT_FORMAT(pLex, pName, pExpectedFormat) \
	POP_TOKEN(pLex, pName); \
	if(!pName->match(pExpectedFormat)) ERROR("Erreur, trouve '" << pName << "' alors que j' attendais '" << pExpectedFormat.str() << "'.")

#define TOKEN_ERROR(pToken) \
	ERROR("Erreur, '" << pToken << "' innatendu.")

bool stringListContains(list<string> &pList, const char *pVal);

class cParser
{
public:
	static void parseFile(cASTree *pTree, cLexer &pLexer);

private:
	static regex dRegexType;
	static regex dRegexInt;
	static regex dRegexBool;
	static regex dRegexExpOperator;
	//static regex dRegexInstOperator;
	static regex dRegexName;

	static void parseBlock(cBlock* pBlock, cLexer &pLexer);
	static cExpression* parseExpression(cLexer &pLexer, list<string> pDelim);
	static cExpression* parseValue(cLexer &pLexer);
	static eType toType(cToken *pToken);
};
